package com.software.cool.utils;

import cn.hutool.core.io.FileUtil;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.GetObjectRequest;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.PutObjectResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Date;

/**
 * @Author: darren
 * @Date: 2021/12/6 10:54
 */
@Slf4j
@Component
public class OssClientUtils {

    /**
     * endpoint是访问OSS的域名。如果您已经在OSS的控制台上 创建了Bucket，请在控制台上查看域名。
     * 如果您还没有创建Bucket，endpoint选择请参看文档中心的“开发人员指南 > 基本概念 > 访问域名”，
     * 链接地址是：https://help.aliyun.com/document_detail/oss/user_guide/oss_concept/endpoint.html?spm=5176.docoss/user_guide/endpoint_region
     * endpoint的格式形如“http://oss-cn-hangzhou.aliyuncs.com/”，注意http://后不带bucket名称，
     * 比如“http://bucket-name.oss-cn-hangzhou.aliyuncs.com”，是错误的endpoint，请去掉其中的“bucket-name”。
     * http://aliyun-online-edu.oss-cn-shenzhen.aliyuncs.com
     */
    private static String endpoint = "http://oss-cn-shenzhen-internal.aliyuncs.com";

    /**
     * accessKeyId和accessKeySecret是OSS的访问密钥，您可以在控制台上创建和查看，
     * 创建和查看访问密钥的链接地址是：https://ak-console.aliyun.com/#/。
     * 注意：accessKeyId和accessKeySecret前后都没有空格，从控制台复制时请检查并去除多余的空格。
     * LTAI5tHcEJjf5jZGpNvrVJ2A
     * wbz7Hb66HuH8y6bl46OPg4Wqlp1vPv
     */
    /**
     * 在线教育
     **/
    private static String accessKeyId = "LTAI5tHcEJjf5jZGpNvrVJ2A";
    private static String accessKeySecret = "wbz7Hb66HuH8y6bl46OPg4Wqlp1vPv";

    /**
     * Bucket用来管理所存储Object的存储空间，详细描述请参看“开发人员指南 > 基本概念 > OSS基本概念介绍”。
     * Bucket命名规范如下：只能包括小写字母，数字和短横线（-），必须以小写字母或者数字开头，长度必须在3-63字节之间。
     */
    /***
     *  在线教育
     * */
    private static String bucketName = "aliyun-online-edu";

    /**
     * 获取阿里云OSS客户端对象
     *
     * @return ossClient
     */
    public static OSSClient getOSSClient() {
        return new OSSClient(endpoint, accessKeyId, accessKeySecret);
    }


    /**
     * 创建存储空间
     *
     * @param bucket
     */
    public static void createBucket(String bucket) {
        OSSClient ossClient = getOSSClient();
        if (StringUtils.isBlank(bucket)) {
            bucket = bucketName;
        }
        if (!ossClient.doesBucketExist(bucket)) {
            ossClient.createBucket(bucket);
        }
        // 关闭OSSClient。
        ossClient.shutdown();
    }


    public static String uploadFile(String objectName, String filePath) {
        // 创建OSSClient实例。
        OSSClient ossClient = getOSSClient();
        File file = new File(filePath);
        PutObjectResult putObjectResult = ossClient.putObject(bucketName, objectName, file);
        String res = putObjectResult.getETag();
        ossClient.shutdown();
        return res;
    }

    public static void downloadFile(String objectName, String filePath) {
        OSSClient ossClient = getOSSClient();
        // 下载OSS文件到本地文件。如果指定的本地文件存在会覆盖，不存在则新建。
        ossClient.getObject(new GetObjectRequest(bucketName, objectName), new File(filePath));
        // 关闭OSSClient。
        ossClient.shutdown();
    }


    public static String uploadStreamFile(String objectName, MultipartFile file) {
        // 创建OSSClient实例。
        String res = null;
        OSSClient ossClient =  getOSSClient();
        try {
            byte[] bytes = file.getBytes();
            InputStream inputStream = new ByteArrayInputStream(bytes);
            PutObjectResult putObjectResult = ossClient.putObject(bucketName, objectName, inputStream);
            res = putObjectResult.getETag();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            ossClient.shutdown();
        }
        return res;
    }

    public static void downloadStreamFile(String objectName, HttpServletResponse response) {
        // 创建OSSClient实例。
        OSSClient ossClient = getOSSClient();
        // ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流。
        OSSObject ossObject = ossClient.getObject(bucketName, objectName);
        // 读取文件内容。
        BufferedInputStream bis = null;
        ByteArrayOutputStream out = null;
        try {
            bis = new BufferedInputStream(ossObject.getObjectContent(), 1024);
            out = new ByteArrayOutputStream();
            byte[] bytes = new byte[1024];
            int len;
            while ((len = bis.read(bytes)) > 0) {
                out.write(bytes, 0, len);
            }
            int totalSize=out.size();
//            log.info("totalSize:"+totalSize);
            String fileName = FileUtil.getName(objectName);
            response.setHeader("content-length", totalSize+"");
            response.setHeader("content-type", MediaType.APPLICATION_OCTET_STREAM_VALUE);
            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            response.setHeader("Content-Disposition", "attachment;filename=" + new String((fileName).getBytes("utf-8"), "ISO-8859-1"));
            response.setCharacterEncoding("UTF-8");
            out.writeTo(response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            ossClient.shutdown();
            try {
                if (bis != null) {
                    bis.close();
                }
                if (out != null) {
                    out.flush();
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void showImage(String objectName, HttpServletResponse response, HttpServletRequest request) {
        // 创建OSSClient实例。
        OSSClient ossClient = getOSSClient();
        // ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流。
        OSSObject ossObject = ossClient.getObject(bucketName, objectName);
        BufferedInputStream bis = null;
        ByteArrayOutputStream out = null;
        String imagePath="";
        try {
            if(ossObject!=null) {
                bis = new BufferedInputStream(ossObject.getObjectContent(), 1024);
                out = new ByteArrayOutputStream();
                byte[] bytes = new byte[1024];
                int len;
                while ((len = bis.read(bytes)) > 0) {
                    out.write(bytes, 0, len);
                }
                response.setCharacterEncoding("UTF-8");
                if (request.getHeader("User-agent").contains("MSIE")) {
                    response.setHeader("Content-Disposition",String.format("inline;filename=%s", URLEncoder.encode("title", "UTF-8")));
                }else {
                    response.setHeader("Content-Disposition", String.format("inline;filename=\"%s\"", new String("title".getBytes("UTF-8"), "ISO8859-1")));
                }
                out.writeTo(response.getOutputStream());
            }
        } catch (Exception e) {
            log.error(e.getMessage(),e);
        } finally {
            try {
                if(bis!=null) {
                    bis.close();
                }
                if(out!=null) {
                    out.flush();
                    out.close();
                }
            } catch (IOException e) {
                //e.printStackTrace();
            }

        }
    }


    /**
     * 获得url链接
     *
     * @param key
     * @return
     */
    public static String getUrl(String key) {
        OSSClient ossClient = getOSSClient();
        // 设置URL过期时间为10年  3600l* 1000*24*365*10
        Date expiration = new Date(System.currentTimeMillis() + 3600L * 1000 * 24 * 365 * 10);
        // 生成URL
        URL url = ossClient.generatePresignedUrl(bucketName, key, expiration);
        ossClient.shutdown();
        if (url != null) {
            return url.toString();
        }
        return null;
    }

    /**
     * 获得图片路径
     *
     * @param fileUrl
     * @return
     */
    public String getImgUrl(String fileUrl) {
        if (!StringUtils.isEmpty(fileUrl)) {
            String[] split = fileUrl.split("/");
            return this.getUrl(fileUrl);
        }
        return null;
    }
}
